package com.bdqn.petmalldemo.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bdqn.petmalldemo.bo.*;
import com.bdqn.petmalldemo.common.ResultCodeEnum;
import com.bdqn.petmalldemo.common.ReturnResult;
import com.bdqn.petmalldemo.common.SystemConstants;
import com.bdqn.petmalldemo.common.TokenCache;
import com.bdqn.petmalldemo.entity.User;
import com.bdqn.petmalldemo.service.UserService;
import com.bdqn.petmalldemo.utils.MD5;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Lenovo
 * @since 2020-02-10
 */
@Api(tags = "用户控制器")
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @ApiOperation(value = "用户注册")
    @PostMapping(value = "/register")
    public ReturnResult register(UserRegisterBo userRegisterBo) {

        //1.相关字段的非空校验
        if (userRegisterBo == null) {
            return ReturnResult.error().code(ResultCodeEnum.FAILED.getCode()).msg(ResultCodeEnum.FAILED.getMsg());
        }
        //用户名不能为空
        if (StringUtils.isEmpty(userRegisterBo.getUsername())) {
            return ReturnResult.error().code(ResultCodeEnum.USERNAME_NULL.getCode()).msg(ResultCodeEnum.USERNAME_NULL.getMsg());
        }
        //邮箱不能为空
        if (StringUtils.isEmpty(userRegisterBo.getEmail())) {
            return ReturnResult.error().code(ResultCodeEnum.EMAIL_NULL.getCode()).msg(ResultCodeEnum.EMAIL_NULL.getMsg());
        }
        //手机号不能为空
        if (StringUtils.isEmpty(userRegisterBo.getPhone())) {
            return ReturnResult.error().code(ResultCodeEnum.PHONE_NULL.getCode()).msg(ResultCodeEnum.PHONE_NULL.getMsg());
        }
        //密码不能为空
        if (StringUtils.isEmpty(userRegisterBo.getPassword())) {
            return ReturnResult.error().code(ResultCodeEnum.PASSWORD_NULL.getCode()).msg(ResultCodeEnum.PASSWORD_NULL.getMsg());
        }
        //执行注册
        userService.userRegister(userRegisterBo);
        return ReturnResult.ok();
    }

    @ApiOperation(value = "用户登录")
    @PostMapping(value = "/login")
    public ReturnResult login(UserLoginBo userLoginBo, HttpServletRequest request) {
        //1.判断该用户名是否为空
        if (StringUtils.isEmpty(userLoginBo.getUsername())) {
            return ReturnResult.error().msg(ResultCodeEnum.USERNAME_NULL.getMsg()).code(ResultCodeEnum.USERNAME_NULL.getCode());
        }
        //判断密码是否为空
        if (StringUtils.isEmpty(userLoginBo.getPassword())) {
            return ReturnResult.error().msg(ResultCodeEnum.PASSWORD_NULL.getMsg()).code(ResultCodeEnum.PASSWORD_NULL.getCode());
        }
        //判断角色是否为空
        if (StringUtils.isEmpty(userLoginBo.getRole())) {
            return ReturnResult.error().msg(ResultCodeEnum.ROLE_NULL.getMsg()).code(ResultCodeEnum.ROLE_NULL.getCode());
        }
        //先获取用户登录ip
        String localAddr = request.getLocalAddr();
        //2.执行登录
        User user = userService.userLogin(userLoginBo, localAddr);
        String token = UUID.randomUUID().toString().replace("-", "");
        //将用户信息存入tokenCache
        TokenCache.put(token, JSONObject.toJSONString(user));
        ReturnResult result = ReturnResult.ok().msg(ResultCodeEnum.SUCCESS.getMsg())
                .code(ResultCodeEnum.SUCCESS.getCode())
                .token(token)
                .data(user);
        log.info(result.toString());
        return result;
    }

    @ApiOperation(value = "修改个信息前的查询")
    @PostMapping(value = "/get")
    public ReturnResult getUserInfoByToken(String token) {
        //先从tokenCache里面取出用户信息
        String jsonUser = TokenCache.get(token);
        //判断当前登录用户状态
        if (StringUtils.isEmpty(jsonUser)) {
            //token失效
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_INVALID.getCode())
                    .msg(ResultCodeEnum.TOKEN_INVALID.getMsg());
        }
        //反序列化
        User user = JSONObject.parseObject(jsonUser, User.class);
        //根据用户ID从数据库中查询用户信息
        user = userService.getById(user.getId());
        //返回一个数据结果
        return ReturnResult.ok().data(user);

    }

    @ApiOperation(value = "修改个人信息")
    @PostMapping(value = "/update")
    public ReturnResult updateUserInfo(UserUpdateBo userUpdateBo) {
        //先根据token判断当前登录用户状态是否有效
        String jsonUser = TokenCache.get(userUpdateBo.getToken());
        if (StringUtils.isEmpty(jsonUser)) {
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_INVALID.getCode())
                    .msg(ResultCodeEnum.TOKEN_INVALID.getMsg());
        }
        //将传递过来的参数转化为User类型
        User user = JSONObject.parseObject(jsonUser, User.class);
        BeanUtils.copyProperties(userUpdateBo, user);
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>().eq("id", user.getId());
        boolean updateResult = userService.update(user, queryWrapper);
        if (updateResult) {
            //更新tokenCache里面的用户信息
            TokenCache.put(userUpdateBo.getToken(), JSONObject.toJSONString(user));
            return ReturnResult.ok().data(user);
        }
        return ReturnResult.error();
    }

    @ApiOperation(value = "安全问题")
    @PostMapping(value = "/questionRecover")
    public ReturnResult questionRecover(QuestionRecoverBo questionRecoverBo) {
        //字段非空校验,只需要保证用户登录的token不能为空,newQuestion和newAnswer不能为空
        if (StringUtils.isEmpty(questionRecoverBo.getToken())) {
            return ReturnResult.error().msg(ResultCodeEnum.USER_NOT_LOGIN.getMsg())
                    .code(ResultCodeEnum.USER_NOT_LOGIN.getCode());
        }
        if (StringUtils.isEmpty(questionRecoverBo.getNewQuestion())) {
            return ReturnResult.error().msg(ResultCodeEnum.QUESTION_NULL.getMsg())
                    .code(ResultCodeEnum.QUESTION_NULL.getCode());
        }
        if (StringUtils.isEmpty(questionRecoverBo.getNewAnswer())) {
            return ReturnResult.error().msg(ResultCodeEnum.ANSWER_NULL.getMsg())
                    .code(ResultCodeEnum.ANSWER_NULL.getCode());
        }
        userService.questionRecover(questionRecoverBo);
        return ReturnResult.ok();
    }

    @ApiOperation(value = "获取用户安全问题")
    @PostMapping(value = "/getPasswordQuestion")
    public ReturnResult getPasswordQuestion(PasswordQuestionBo passwordQuestionBo) {
        //校验用户名和邮箱不能为空
        if (StringUtils.isEmpty(passwordQuestionBo.getEmail())) {
            return ReturnResult.error().code(ResultCodeEnum.EMAIL_NULL.getCode())
                    .msg(ResultCodeEnum.EMAIL_NULL.getMsg());
        }
        if (StringUtils.isEmpty(passwordQuestionBo.getUsername())) {
            return ReturnResult.error().code(ResultCodeEnum.USERNAME_NULL.getCode())
                    .msg(ResultCodeEnum.USERNAME_NULL.getMsg());
        }
        String question = userService.getPasswordQuestion(passwordQuestionBo);
        return ReturnResult.ok().data(question);
    }

    @ApiOperation(value = "校验安全问题答案")
    @PostMapping(value = "/passwordRecover")
    public ReturnResult passwordRecover(PasswordQuestionBo passwordQuestionBo){
        //校验用户名，邮箱，安全问题，答案不能为空
        if (StringUtils.isEmpty(passwordQuestionBo.getEmail())) {
            return ReturnResult.error().code(ResultCodeEnum.EMAIL_NULL.getCode())
                    .msg(ResultCodeEnum.EMAIL_NULL.getMsg());
        }
        if (StringUtils.isEmpty(passwordQuestionBo.getUsername())) {
            return ReturnResult.error().code(ResultCodeEnum.USERNAME_NULL.getCode())
                    .msg(ResultCodeEnum.USERNAME_NULL.getMsg());
        }
        if (StringUtils.isEmpty(passwordQuestionBo.getQuestion())) {
            return ReturnResult.error().code(ResultCodeEnum.QUESTION_NULL.getCode())
                    .msg(ResultCodeEnum.QUESTION_NULL.getMsg());
        }
        if (StringUtils.isEmpty(passwordQuestionBo.getAnswer())) {
            return ReturnResult.error().code(ResultCodeEnum.ANSWER_NULL.getCode())
                    .msg(ResultCodeEnum.ANSWER_NULL.getMsg());
        }
        String randomPassword = userService.passwordRecover(passwordQuestionBo);
        return ReturnResult.ok().data(randomPassword);
    }

    @ApiOperation(value = "运营人员后台会员管理列表接口")
    @PostMapping(value = "/search")
    public ReturnResult search
            (@ApiParam(name = "token",value = "当前登录用户的token",required = true) String token,
             @ApiParam(name = "status",value = "状态")
             Integer status,
             @ApiParam(name = "keyword",value = "搜索关键字")
             String keyword){
        if (StringUtils.isEmpty(token)) {
            return  ReturnResult.error().code(ResultCodeEnum.TOKEN_NULL.getCode())
                    .msg(ResultCodeEnum.TOKEN_NULL.getMsg());
        }
        //验证当前登录用户信息是否生效
        String jsonUser = TokenCache.get(token);
        if (StringUtils.isEmpty(jsonUser)) {
            return  ReturnResult.error().code(ResultCodeEnum.TOKEN_INVALID.getCode())
                    .msg(ResultCodeEnum.TOKEN_INVALID.getMsg());
        }
        Map<String, Object> map = userService.searchMember(status,keyword);
        ReturnResult data = ReturnResult.ok().data(map);
        log.info(data.toString());
        return data;
    }

    @ApiOperation(value = "禁用/激活会员")
    @PostMapping(value = "/updateStatus")
    public ReturnResult updateStatus(
            @ApiParam(name = "token",value = "当前用户登录token",required = true)
            String token,
            @ApiParam(name = "userId",value = "要修改的用户Id",required = true)
            String userId,
            @ApiParam(name = "status",value = "要修改的状态",required = true)
            Integer status
            ){
            //token,用户Id,状态三个参数的非空校验
        if (StringUtils.isEmpty(token)) {
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_NULL.getCode())
                    .msg(ResultCodeEnum.TOKEN_NULL.getMsg());
        }
        if (StringUtils.isEmpty(userId)) {
            return ReturnResult.error().code(ResultCodeEnum.ID_NULL.getCode())
                    .msg(ResultCodeEnum.ID_NULL.getMsg());
        }
        if (StringUtils.isEmpty(status)) {
            return ReturnResult.error().code(ResultCodeEnum.STATUS_NULL.getCode())
                    .msg(ResultCodeEnum.STATUS_NULL.getMsg());
        }
        //校验当前用户token是否为空
        String jsonUser = TokenCache.get(token);
        if (StringUtils.isEmpty(jsonUser)) {
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_INVALID.getCode())
                    .msg(ResultCodeEnum.TOKEN_INVALID.getMsg());
        }
        userService.updateStatus(userId,status);
        return  ReturnResult.ok();
    }

    @ApiOperation(value = "检查当前登录用户的状态")
    @PostMapping(value = "/checkActive")
    public ReturnResult checkActive(
            @ApiParam(name = "token",value = "当前登录用的token",required = true)
            String token
    ){
        if (StringUtils.isEmpty(token)) {
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_NULL.getCode())
                    .msg(ResultCodeEnum.TOKEN_NULL.getMsg());
        }
        //校验当前用户token是否为空
        String jsonUser = TokenCache.get(token);
        if (StringUtils.isEmpty(jsonUser)) {
            return ReturnResult.ok().data(false);
        }
        User user = JSONObject.parseObject(jsonUser, User.class);
        boolean checkResult = userService.checkActive(user.getId());
        return ReturnResult.ok().data(checkResult);
    }

    @ApiOperation(value = "修改密码")
    @PostMapping(value = "/updatePassword")
    public ReturnResult updatePassword(UpdatePasswordBo updatePasswordBo){
        //校验参数
        if (StringUtils.isEmpty(updatePasswordBo.getToken())||
                StringUtils.isEmpty(updatePasswordBo.getNewPassword())||
                StringUtils.isEmpty(updatePasswordBo.getOldPassword())||
                StringUtils.isEmpty(updatePasswordBo.getRePassword())) {
            return ReturnResult.error().code(ResultCodeEnum.ARGS_NULL.getCode())
                    .msg(ResultCodeEnum.ARGS_NULL.getMsg());
        }
        //校验当前Token是否有效
        String jsonUser = TokenCache.get(updatePasswordBo.getToken());
        if (StringUtils.isEmpty(jsonUser)) {
            return ReturnResult.error().code(ResultCodeEnum.TOKEN_INVALID.getCode())
                    .msg(ResultCodeEnum.TOKEN_INVALID.getMsg());
        }
        //执行修改
        User user = JSONObject.parseObject(jsonUser, User.class);
        User userById = userService.getById(user.getId());
        //先校验原密码是否正确
        if (!userById.getPassword().equals(MD5.encode(updatePasswordBo.getOldPassword()+ SystemConstants.MD5_SLAT))) {
            return ReturnResult.error().code(ResultCodeEnum.OLD_PASSWORD_ERROR.getCode())
                    .msg(ResultCodeEnum.OLD_PASSWORD_ERROR.getMsg());
        }
        //校验传递过来的新密码和数据库中的旧密码是否一致
        if (userById.getPassword().equals(MD5.encode(updatePasswordBo.getNewPassword()+ SystemConstants.MD5_SLAT))) {
            return ReturnResult.error().code(ResultCodeEnum.NEW_PASSWORD_EQUALS_OLD_PASSWORD.getCode())
                    .msg(ResultCodeEnum.NEW_PASSWORD_EQUALS_OLD_PASSWORD.getMsg());
        }
        //校验两个新密码是否一致
        if (!updatePasswordBo.getNewPassword().equals(updatePasswordBo.getRePassword())) {
            return ReturnResult.error().code(ResultCodeEnum.NEW_PASSWORD_NOT_EQUALS.getCode())
                    .msg(ResultCodeEnum.NEW_PASSWORD_NOT_EQUALS.getMsg());
        }
        userById.setPassword(MD5.encode(updatePasswordBo.getNewPassword()+SystemConstants.MD5_SLAT));
        userService.updateById(userById);
        return  ReturnResult.ok();
    }


    }



